package org.lex.app.prefs;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;

import org.lex.utils.text.Splitter;


public class ResourceManager {
	private File resourceHome = null;
	private String globalResourceMapName = null;
	private ResourceMap globalResourceMap = null;
	private Map<Class<?>, ResourceMap> map = null;

	public ResourceManager(File home, String name) {
		this.resourceHome = home;
		this.globalResourceMapName = name + ".properties";
		this.map = new Hashtable<Class<?>, ResourceMap>();
		if (false == home.exists() || false == home.isDirectory())
			home.mkdirs();
	}

	public ResourceMap getResourceMap() {
		if (null == this.globalResourceMap) {
			this.globalResourceMap = this.createResourceMap(new File(resourceHome, globalResourceMapName));
		}
		return this.globalResourceMap;
	}

	public ResourceMap getResourceMap(Class<?> key) {
		// XXX �Ƿ�Ҫ��ResourceMap��ActionMap������в�νṹ��?
		ResourceMap rm = map.get(key);
		if (null == rm) {
			rm = this.createResourceMap(this.getResourceMapFile(key));
			map.put(key, rm);
		}
		return rm;
	}

	public void load() throws IOException {
		boolean hasError = false;
		IOException lastError = null;
		ArrayList<String> errorMessages = new ArrayList<String>();
		Iterator<Map.Entry<Class<?>, ResourceMap>> iter = map.entrySet().iterator();
		ResourceMap rm = this.getResourceMap();
		do {
			try {
				rm.load();
			} catch (IOException e) {
				hasError = true;
				errorMessages.add(e.getLocalizedMessage());
				lastError = e;
			}
			if (iter.hasNext())
				rm = iter.next().getValue();
			else
				break;
		} while (true);
		if (hasError)
			throw new IOException(errorMessages.toString(), lastError);
	}

	public void save() throws IOException {
		boolean hasError = false;
		IOException lastError = null;
		ArrayList<String> errorMessages = new ArrayList<String>();
		Iterator<Map.Entry<Class<?>, ResourceMap>> iter = map.entrySet().iterator();
		ResourceMap rm = this.getResourceMap();
		do {
			try {
				rm.store();
			} catch (IOException e) {
				hasError = true;
				errorMessages.add(e.getLocalizedMessage());
				lastError = e;
			}
			if (iter.hasNext())
				rm = iter.next().getValue();
			else
				break;
		} while (true);
		if (hasError)
			throw new IOException(errorMessages.toString(), lastError);
	}

	private File getResourceMapFile(Class<?> clz) {
		String className = clz.getCanonicalName();
		if (null == className)
			className = clz.getName();
		String[] path = Splitter.DotSplitter.split(className);
		File dir = this.resourceHome;
		for (int i = 0; i < path.length - 1; i++)
			dir = new File(dir, path[i]);
		if (false == dir.exists() || false == dir.isDirectory())
			dir.mkdirs();
		return new File(dir, path[path.length - 1] + ".properties");
	}

	private ResourceMap createResourceMap(File file) {
		ResourceMap rm = new PropertyFileResourceMap(file);
		try {
			rm.load();
		} catch (IOException e) {
			System.err.println("create ResourceMap error: " + e.getMessage());
		}
		return rm;
	}
}
